#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '

__author__ = '许文杰'

# 私有函数
def _private_one():
    print('private_one')

def _private_two():
    print('private_two')

# 公开函数
def public_func(name):
    print(name)
    _private_one()
    _private_two()

class Student(object):
    male = 'man' # 类属性 当该类的对象调用实例属性，却没有找到调用的实例对象时，就会去类属性里面找。
    def __init__(self, name, score):
        self.name = name  # 实例属性
        self.score = score

    def print_stu(self):
        print('name: %s score: %d' %(self.name, self.score))


class StudentOne(object):
    def __init__(self, name, score):
        self.__name = name # 私有属性，外部不可直接访问和修改
        self.__score = score

    # 私有属性不可通过对象获取私有属性的值，可通过方法实现获取私有属性的值
    def get_name(self):
        return self.__name
    def get_score(self):
        return self.__score

    # 私有属性不可通过对象修改私有属性的值，可通过方法实现修改私有属性的值
    def set_name(self, name):
        self.__name = name
    def set_score(self, score):
        self.__score = score

class Screen(object):
    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, value):
        if value >= 0:
            self._width = value
        else:
            raise ValueError('value must be bigger than 0')
    @property
    def height(self):
        return self._height

    @height.setter
    def height(self, value):
        if value > 0:
            self._height = value
        else:
            raise ValueError('value must be bigger than 0')

    @property
    def resolution(self):
        return self._width * self._height

# 继承和多态
class Person(object):
    def eat(self):
        print('person eat food')

class Man(Person):
    def eat(self):
        print('man eat food')

class Women(Person):
    def eat(self):
        print('women eat food')

class Dashi(object):
    def eat(self):
        print('dashi eat food')

def twice_eat(person):
    person.eat()
    person.eat()

def set_score(self, score):
    self.score = score

# 动态给student类添加方法
Student.set_score = set_score

if __name__ == '__main__':
    # stu = Student('xuwenie', 100)
    # stu.name = 'yuyi' # 可以获取和改变该属性的值，如果不想获取和外部修改值，需要把self.name = name 改为 self.__name = name，就成为了私有属性，外部不可获取和更改
    # stu.score = 0
    # stu.print_stu()
    #
    # stu1 = StudentOne('dongkeng', 0)
    # print(stu1.get_name(), stu1.get_score())
    #
    # stu1.set_name('xiaoqiang')
    # stu1.set_score(99)
    # print(stu1.get_name(), stu1.get_score())

    # person = Person()
    # person.eat()

    # man = Man()
    # man.eat()

    # women = Women()
    # women.eat()

    # dashi = Dashi()
    # dashi.eat()

    # twice_eat(person)
    # twice_eat(man)
    # twice_eat(women)
    # twice_eat(dashi) # 则不一定需要传入person类型。我们只需要保证传入的对象有一个run()方法就可以

    # 判断基本数据类型，使用type()函数
    # 函数返回的是对应的Class类型
    # if type('123') == type('adv'):
    #     print('str is %d' % True)
    #
    # if isinstance(man, Person):
    #     print(True)
    # else:
    #     print(False)
    #
    # if isinstance(dashi, Person):
    #     print(True)
    # else:
    #     print(False)
    #
    # print(dir(man))
    #
    # stu = Student('xuwnejie', 100)
    # # hasattr判断对象stu有木有name和male属性
    # print(hasattr(stu, 'male'), hasattr(stu, 'name'))
    # # setattr为stu对象设置male属性
    # setattr(stu, 'male', 'man')
    # print(hasattr(stu, 'male'))
    # # 获取对象stu的male属性
    # print(getattr(stu, 'male'))
    # print(stu.male)
    # stu.sss = 'hahaha' # 如果student类没有sss实例属性和类属性，则会动态添加进去
    # print(stu.sss)
    # stu.set_score(100) # 使用动态添加的方法改变score的值
    # print(stu.score)

    # 获取该对象的方法print_stu
    # p = getattr(stu, 'print_stu')
    # p()

    screen = Screen()
    screen.width = 10
    screen.height = 20
    print(screen.width, screen.height, screen.resolution)